<template>
  <form class="ui-form" @submit="formSubmit">
    <slot></slot>
  </form>
</template>

<script>
export default {
  name: "uiForm",
  provide() {
    return {
      uiform: this
    };
  },
  props: {
    validateTrigger: {
      type: String,
      default: "onBlur"
    },
    inputAlign: String,
    labelWidth: {
      type: String
    }
  },
  data() {
    return {
      fields: []
    };
  },
  created() {},
  mounted() {},
  methods: {
    formSubmit(callback) {
      console.log(`form is submit`);
      this.validate()
        .then(() => {
          if (callback) {
            callback();
          }
          this.$emit("submit", values);
        })
        .catch(errors => {
          console.log(errors);
          // this.$emit("failed", {
          //   values,
          //   errors
          // });

          // if (this.scrollToError) {
          //   this.scrollToField(errors[0].name);
          // }
        });
    },

    validateSeq() {
      return new Promise((resolve, reject) => {
        const errors = [];

        this.fields
          .reduce(
            (promise, field) =>
              promise.then(() => {
                if (!errors.length) {
                  return field.validate().then(error => {
                    if (error) {
                      errors.push(error);
                    }
                  });
                }
              }),
            Promise.resolve()
          )
          .then(() => {
            if (errors.length) {
              reject(errors);
            } else {
              resolve();
            }
          });
      });
    },
    validateAll() {
      return new Promise((resolve, reject) => {
        Promise.all(this.fields.map(item => item.validate())).then(errors => {
          errors = errors.filter(item => item);

          if (errors.length) {
            reject(errors);
          } else {
            resolve();
          }
        });
      });
    },

    // @exposed-api
    validate(name) {
      if (name) {
        return this.validateField(name);
      }
      return this.validateFirst ? this.validateSeq() : this.validateAll();
    },

    validateField(name) {
      const matched = this.fields.filter(item => item.name === name);
      if (matched.length) {
        return new Promise((resolve, reject) => {
          matched[0].validate().then(error => {
            if (error) {
              reject(error);
            } else {
              resolve();
            }
          });
        });
      }

      return Promise.reject();
    }
  }
};
</script>

<style scoped lang="scss" >
</style>
